package com.liarjo.my_website_api.security;

import cn.hutool.core.util.StrUtil;
import com.liarjo.my_website_api.util.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.PathContainer;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;

import java.io.IOException;
import java.util.Set;

@Component
public class JwtFilter extends OncePerRequestFilter {
    private static final PathPatternParser parser = new PathPatternParser();
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private LoginService loginService;
    private static final Set<PathPattern> WHITE_LIST = Set.of(
            parser.parse("/api/admin/login"),
            parser.parse("/api/public/**")
    );

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 白名单
        String requestUri = request.getRequestURI();
        boolean isWhiteListed = WHITE_LIST.stream().anyMatch(pattern -> pattern.matches(PathContainer.parsePath(requestUri)));
        if (isWhiteListed) {
            filterChain.doFilter(request, response);
            return;
        }
        // 判断token格式
        String authorizationHeader = request.getHeader("Authorization");
        if (StrUtil.isBlank(authorizationHeader)) {
            throw new RuntimeException("没有token");
        }
        if (!authorizationHeader.startsWith("Bearer ")) {
            throw new RuntimeException("token格式错误");
        }
        // 验证token
        String jwt = authorizationHeader.substring(7);
        JwtUtil.JwtStatus tokenStatus = jwtUtil.validateToken(jwt);
        if (tokenStatus != JwtUtil.JwtStatus.TOKEN_VALID) {
            throw new RuntimeException("token无效");
        }
        // 根据token获取用户
        Claims claims = jwtUtil.parseToken(jwt);
        Long userId = Long.parseLong(claims.getSubject());
        UserDetails userDetails = loginService.selectUserById(userId);

        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities()
        );
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        filterChain.doFilter(request, response);
    }
}
